package com.ruoyi.act.controller.commom;

import com.github.pagehelper.Page;
import com.ruoyi.act.domain.TProcessModel;
import com.ruoyi.act.domain.VO.HisTaskVO;
import com.ruoyi.act.domain.VO.ProcessInstanceListVO;
import com.ruoyi.act.service.ITProcessModelService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.impl.SysDictDataServiceImpl;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.HistoricVariableInstanceEntityImpl;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.ArrayUtils;
import org.thymeleaf.util.ListUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author badcat
 * @date 2021-09-01 0:31
 */
@Controller
@RequestMapping("/act/processInstance")
public class ProcessInstanceController extends BaseController {

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private TaskService taskService;

    private String prefix = "act/definition/needDealt";

    @RequestMapping("/myInstanceList")
    public String myInstanceList(Model model) {
        return prefix + "/myInstanceList";
    }

    @RequestMapping("/myManageStaffInstanceList")
    public String myManageStaffInstanceList(Model model) {
        return prefix + "/myManageStaffInstanceList";
    }

    /**
     * 查询我发起的某个流程定义的实例列表
     * @param key 流程定义key
     * @param model
     * @param firstResult 起始索引
     * @param maxResults  要查询多少条
     * @return
     */
    @ResponseBody
    @RequestMapping("/getMyInstance")
    public TableDataInfo getMyInstance(Model model) throws Exception {
        String name = this.getRequest().getParameter("name");
        String beginTime = this.getRequest().getParameter("beginTime");
        String endTime = this.getRequest().getParameter("endTime");
        String processKey = this.getRequest().getParameter("processKey");
        String status = this.getRequest().getParameter("status");

        SysUser sysUser = ShiroUtils.getSysUser();
        String loginName = sysUser.getLoginName();
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        Page<ProcessInstanceListVO> voList =new Page<>();
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
                .startedBy(loginName)
                .orderByProcessInstanceStartTime()
                .desc();
        if(StringUtils.isNotBlank(name)){
            query.processInstanceNameLike(name);
        }
        if(StringUtils.isNotBlank(beginTime)){
            Date beginTime_date = DateUtils.parseDate(beginTime, "yyyy-MM-dd");
            query.startedAfter(beginTime_date);
        }
        if(StringUtils.isNotBlank(endTime)){
            Date endTime_date = DateUtils.parseDate(endTime, "yyyy-MM-dd");
            query.startedBefore(endTime_date);
        }
        if(StringUtils.isNotBlank(processKey)){
            query.processDefinitionKey(processKey);
        }
        if(StringUtils.isNotBlank(status)){
            if(StringUtils.equals("act_complete_type_001", status)){
                //已完成
                query.finished();
            }else{
                //未完成
                query.unfinished();
            }
        }
        List<HistoricProcessInstance> listPage = query.listPage((pageNum - 1) * pageSize, pageSize);
        voList.setTotal(query.count());
        voList.setPageNum(pageNum);
        voList.setPageSize(pageSize);
        toProcessInstanceListVO(voList, listPage);
        return getDataTable(voList);
    }

    public void toProcessInstanceListVO(Page<ProcessInstanceListVO> voList, List<HistoricProcessInstance> list) {

        for (HistoricProcessInstance e : list) {
            ProcessInstanceListVO vo = new ProcessInstanceListVO();
            vo.setId(e.getId());
            vo.setBusinessKey(e.getBusinessKey());
            vo.setProcessDefinitionId(e.getProcessDefinitionId());
            vo.setProcessDefinitionKey(e.getProcessDefinitionKey());
            vo.setProcessDefinitionName(e.getProcessDefinitionName());
            vo.setEndTime(e.getEndTime());
            vo.setStartTime(e.getStartTime());
            vo.setStartUserId(e.getStartUserId());
            if(e.getEndTime() != null){
                vo.setCompleteType("act_complete_type_001");
            }else{
                vo.setCompleteType("act_complete_type_002");
            }
            //获取每个流程中所有流转记录
            List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().processInstanceId(e.getId())
                    .list();
//            for(HistoricVariableInstance historicVariableInstance : historicVariableInstances){
//                //获取每个流程的标题
//                HistoricVariableInstanceEntityImpl historicVariableInstanceEntity = (HistoricVariableInstanceEntityImpl) historicVariableInstance;
//                String name = historicVariableInstanceEntity.getName();
//                if("system_type".equals(name)){
//                    String textValue = historicVariableInstanceEntity.getTextValue();
//                    if(!"".equals(textValue) && textValue != null){
//                        SysDictData sysDictData = sysDictDataMapper.selectDictDataByValue(textValue);
//                        if(sysDictData != null){
//                            vo.setSystemName(sysDictData.getDictLabel());
//                        }
//                    }
//                }
//                if("title".equals(name)){
//                    String textValue = historicVariableInstanceEntity.getTextValue();
//                    if(textValue != null && textValue != ""){
//                        vo.setTitle(textValue);
//                    }
//                }
//                //获取每个流程的最新节点处理人
//                List<HistoricTaskInstance> processList = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicVariableInstance.getProcessInstanceId()).orderByTaskCreateTime().desc().list();
//                HistoricTaskInstance historicTaskInstance = processList.get(0);
//                SysUser sysUser = iSysUserService.selectUserByLoginName(processList.get(processList.size()-1).getAssignee());
//                //流程未结束
//                if(historicTaskInstance.getEndTime() == null){
//                    if(sysUser == null){
//                        vo.setCurrentHandler(sysUser.getUserName());
//                    }else{
//                        vo.setCurrentHandler(historicTaskInstance.getAssignee());
//                    }
//                    if(vo.getCurrentHandler() == null){
//                        vo.setCurrentHandler("等待领导审批");
//                    }
//                }else{//流程已结束
//                    vo.setCurrentHandler("已结束");
//                }
//
//            }
            historicVariableInstances.stream()
                    .filter(h -> StringUtils.containsAny(h.getVariableName(), "system_type", "title"))
                    .forEach(h -> {
                        //给列表的系统名称和标题属性赋值
                        String textValue = (String) h.getValue();
                        if (StringUtils.equals("title", h.getVariableName()) && StringUtils.isNotEmpty(textValue)) {
                            vo.setTitle(textValue);
                        } else if (StringUtils.equals("system_type", h.getVariableName()) && StringUtils.isNotEmpty(textValue)) {
                            SysDictData sysDictData = sysDictDataMapper.selectDictDataByValue(textValue);
                            if (sysDictData != null) {
                                vo.setSystemName(sysDictData.getDictLabel());
                            }
                        }
                    });
            //获取每个流程的最新节点处理人
            List<HistoricTaskInstance> processList = historyService.createHistoricTaskInstanceQuery().processInstanceId(e.getId()).orderByTaskCreateTime().desc().list();
            try {
                HistoricTaskInstance historicTaskInstance = processList.get(0);
                //流程未结束
                if(historicTaskInstance.getEndTime() == null){
                    vo.setCurrentHandler(iSysUserService.selectUserUserNameListByLoginName(historicTaskInstance.getAssignee()));
                    if(vo.getCurrentHandler() == null){
                        List<HistoricVariableInstance> leaderGroup = historyService.createHistoricVariableInstanceQuery()
                                .processInstanceId(historicTaskInstance.getProcessInstanceId())
                                .variableName("leaderGroup").list();
                        List<HistoricVariableInstance> collect = leaderGroup.stream().filter(l -> StringUtils.isNotEmpty(l.getTaskId()))
                                .filter(l -> StringUtils.isNotEmpty(((HistoricVariableInstanceEntityImpl) l).getExecutionId()))
                                .collect(Collectors.toList());
                        String value = (String) collect.get(0).getValue();
                        List leaderGroupList = iSysUserService.selectUserUserNameListByRoleName(value);
                        StringBuilder sb = new StringBuilder();
                        leaderGroupList.stream().forEach(l -> {
                            sb.append(l + ",");
                        });
                        String leaderGroupStr = sb.toString();
                        vo.setCurrentHandler(leaderGroupStr.substring(0,leaderGroupStr.length() - 1));
                    }
                }else{//流程已结束
                    vo.setCurrentHandler("已结束");
                }
            } catch (Exception ex) {
                throw new RuntimeException("发起的某个流程不完整，请检查！");
            }
            voList.add(vo);
        }
    }

    @ResponseBody
    @RequestMapping("/deleteInstanceById")
    public AjaxResult deleteInstanceById(@RequestParam("instanceId") String instanceId){
        try {
            runtimeService.deleteProcessInstance(instanceId,"发起人删除");
        } catch (Exception e) {
        }
        historyService.deleteHistoricProcessInstance(instanceId);
        return AjaxResult.success();
    }

    @ResponseBody
    @RequestMapping("/backTask")
    public AjaxResult backTask(@RequestParam("instanceId") String instanceId){
        ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(instanceId)
                .singleResult();

        Object o = runtimeService.getVariable(instanceId, "backMsgKey");
        String backMsgKey = "";
        if(o != null){
            backMsgKey = o.toString();
        }
        if(StringUtils.isBlank(backMsgKey)){
            return AjaxResult.error();
        }
        Execution execution = this.runtimeService.createExecutionQuery()
                .messageEventSubscriptionName(backMsgKey)
                .processInstanceId(instanceId)
                .singleResult();

        this.runtimeService.messageEventReceived(backMsgKey, execution.getId());
        return AjaxResult.success();
    }
}
